// 手写promise
class Promise {
    constructor(executor) {
        // promise状态 跟 result
        this.PromiseState = "pending";
        this.PromiseResult = null;
        this.callbacks = []; // 收集多个回调
        const self = this;
        function resolve(data) {
            setTimeout(() => {
                // promise状态只能更改一次
                if (self.PromiseState !== "pending") return;
                self.PromiseState = "fulfilled";
                self.PromiseResult = data;
                self.callbacks.forEach(item => {
                    item.onResolve && item.onResolve(data);
                })
            })
        };
        function reject(data) {
            setTimeout(() => {
                // promise状态只能更改一次
                if (self.PromiseState !== "pending") return;
                self.PromiseState = "rejected";
                self.PromiseResult = data;
                self.callbacks.forEach(item => {
                    item.onReject && item.onReject(data);
                })
            })
        };
        try {
            executor(resolve, reject);
        } catch (error) {
            reject(error)
        }
    }
    then(onResolve, onReject) {
        let self = this;
        if (typeof onResolve !== "function") {
            onResolve = value => value;
        }
        if (typeof onReject !== "function") {
            onReject = reason => {
                throw reason;
            };
        }
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if (this.PromiseState === "fulfilled") {
                    try {
                        let result = onResolve(this.PromiseResult);
                        if (result instanceof Promise) {
                            result.then(v => {
                                resolve(v)
                            }, r => {
                                reject(r)
                            })
                        } else {
                            resolve(result)
                        }
                    } catch (error) {
                        reject(error)
                    }
                } else if (this.PromiseState === "rejected") {
                    onReject(this.PromiseResult)
                } else {
                    // pending状态 保存方法方便在resolve跟reject函数调用
                    this.callbacks.push({
                        onResolve: onResolve || function () {
                            try {
                                let result = onResolve(self.PromiseResult);
                                if (result instanceof Promise) {
                                    result.then(v => {
                                        resolve(v)
                                    }, r => {
                                        reject(r)
                                    })
                                } else {
                                    resolve(result)
                                }
                            } catch (error) {
                                reject(error)
                            }
                        },
                        onReject: onReject || function () {
                            try {
                                let result = onReject(self.PromiseResult);
                                if (result instanceof Promise) {
                                    result.then(v => {
                                        resolve(v)
                                    }, r => {
                                        reject(r)
                                    })
                                } else {
                                    resolve(result)
                                }
                            } catch (error) {
                                reject(error)
                            }
                        },
                    });
                }
            })
        })
    }
    catch(onReject) {
        return this.then(undefined, onReject)
    }
    static resolve(value) {
        return new Promise((resolve, reject) => {
            if (value instanceof Promise) {
                value.then(v => {
                    resolve(v)
                }, r => {
                    reject(r)
                })
            } else {
                resolve(value)
            }
        })
    }
    static reject(reason) {
        return new Promise((resolve, reject) => {
            reject(reason)
        })
    }
    static all(promises) {
        let resultArr = [];
        return new Promise((resolve, reject) => {
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(v => {
                    resultArr.push(v);
                    resultArr.length === promises.length && resolve(resultArr);
                }, r => {
                    reject(r);
                })
            }
        })
    }
    static race(promises) {
        return new Promise((resolve, reject) => {
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(v => {
                    resolve(v);
                }, r => {
                    resolve(rejectArr);
                })
            }
        })
    }
}
export default Promise